02장 다이오드 기본 회로¶
- 이름: 홍길동
- 학번: 2024123456
- 조: 1
공통 코드¶
In [1]:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import re
import io
from scipy.signal import savgol_filter # 사비츠키-골레이(Savitzky-Golay) 필터
from numpy import nan, inf
from IPython.display import Image
# %matplotlib tk
# %matplotlib inline
def tangent_line(f, x):
h = 1e-4
d = (f(x+h) - f(x-h)) / (2*h)
return lambda t: d*t - d*x + f(x)
def tangent_line_end(f, x):
h = 1e-4
d = (f(x) - f(x-h)) / (h)
return lambda t: d*t - d*x + f(x)
def tangent_line_and_gradient(f, x):
h = 1e-4
d = (f(x+h) - f(x-h)) / (2*h)
return (lambda t: d*t - d*x + f(x)), d
def tangent_line_and_gradient_end(f, x):
h = 1e-4
d = (f(x) - f(x-h)) / (h)
return (lambda t: d*t - d*x + f(x)), d
def derivative(f, x):
h = 1e-4
d = (f(x+h) - f(x-h)) / (2*h)
return d
def get_simulation_result(file_name, start=0, end=-1):
if end == -1:
end = None
else:
end += 1
with open(file_name, encoding='cp1252') as data_file:
lines = data_file.read()
occurrences = lines.count('Step Information:')
data_file.seek(0)
line = data_file.readline()
labels = re.split(', | ,|\t', line)
labels = [s.strip().upper() for s in labels]
data = {}
if (occurrences == 0):
for label in labels:
data[label] = []
for line in data_file:
values = re.split(', | ,|\t', line)
for i in range(len(values)):
value = float(values[i]) * 1000
data[labels[i]].append(value)
else:
labels_all =[]
lines = data_file.readline() # skip first line starting with 'Step Information:'
for idx in range(occurrences):
labels_new = []
for label in labels:
labels_new.append('(%s)@%d' % (label, idx+1))
labels_all += labels_new
for label_new in labels_new:
data[label_new] = []
for line in data_file:
if (line.startswith('Step Information:')):
break
values = re.split(', | ,|\t', line)
for i in range(len(values)):
value = float(values[i]) * 1000
data[labels_new[i]].append(value)
labels = labels_all
for label in labels:
data[label] = np.array(data[label][start:end])
# print("labels = ", end='')
# print(list(data.keys()))
for label in list(data.keys()):
print("data['%s'] : sample number = %d" % (label, len(data[label])))
return data
def get_oscilloscpoe_result_tektronix(file_name, start=0, end=-1):
if end == -1:
end = None
else:
end += 1
df = pd.read_csv(file_name, header=None, encoding='cp1252',low_memory=False)
label_ri = df.loc[df.iloc[:,0] == 'Source', 1].index
ci = 0
data = {}
data['TIME'] = df.iloc[start:end, 3].to_numpy().astype(float)
data['TIME'] -= data['TIME'][0]
for idx in range(df.shape[1]//6):
label = df.iloc[label_ri, ci+1].item()
data[label] = df.iloc[start:end,ci+4].to_numpy().astype(float)
ci += 6
# print("labels = ", end='')
# print(list(data.keys()))
for label in list(data.keys()):
print("data['%s'] : sample number = %d" % (label, len(data[label])))
return data
def print_array(label, values):
print('%s = [' % label, end='')
for idx, vd in enumerate(values):
print('{:11.3f}'.format(vd), end='')
if (idx+1 != len(values)):
print(', ', end='')
print(']')
def print_value(label, value):
print('%s = ' % label, end='')
print('{:11.3f}'.format(value))
def print_value_to_string(label, value):
output = io.StringIO()
print('%s = ' % label, end='', file=output)
print('{:11.3f}'.format(value), file=output)
captured = output.getvalue()
return captured
def draw_plot(xs, ys, label, style_idx, color_idx=-1, marker_num=16, scatter=False, scatter_s=2):
linestyle = ['-', '-', '-', '-', '-',
'-', '-', '-', '-', '-',
'-', '-', '-', '-', '-',
'-', '-', '-', '-', '-',
'-', '-', '-', '-', '-']
colors = ['blue', 'green', 'red', 'orange', 'purple',
'cyan', 'darkseagreen', 'brown', 'goldenrod', 'darkviolet',
'steelblue', 'limegreen', 'tomato', 'tan', 'deeppink',
'navy', 'lightgreen', 'indianred', 'khaki', 'rebeccapurple',
'slategray', 'forestgreen', 'orangered', 'wheat', 'orchid']
markers = ['o', 'v', '<', 's', 'p',
'h', '*', 'X', 'x', '^',
'>', 'P', 'D', 'H', 'd',
'|', '-', '4' '5', '6',
'7', '8', '9 ', '10', '+']
if color_idx < 0:
color_idx = style_idx
if isinstance(xs, list):
xs = np.array(xs)
if isinstance(ys, list):
ys = np.array(ys)
if (marker_num == 0):
selected_markevery = None
selected_marker = None
elif not isinstance(xs, np.ndarray):
selected_markevery = None
selected_marker = markers[style_idx]
elif (marker_num > 0):
markeverys = []
if xs[0] > xs[-1]:
first_idx = -1
else:
first_idx = 0
x_step = (xs.max() - xs.min()) / marker_num
for idx in range(len(markers)):
x_start = xs.min() + ((x_step / (len(markers) + 1)) * idx)
marker_list = []
for j in range(marker_num):
tmp_array = np.where(xs > (x_start + (x_step * j)))
if (len(tmp_array[0]) > 0):
marker_list.append(tmp_array[0][first_idx])
markeverys.append(marker_list)
selected_markevery = markeverys[style_idx]
selected_marker = markers[style_idx]
else:
selected_markevery = None
selected_marker = markers[style_idx]
if (scatter):
plt.scatter(xs, ys, color=colors[color_idx], marker=selected_marker, s=scatter_s, label=label)
else:
plt.plot(xs, ys, ls=linestyle[style_idx], color=colors[color_idx], marker=selected_marker, markevery=selected_markevery, label=label)
if (label != None):
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.)
def set_plot_size(xrate, yrate):
if (len(set_plot_size.g_plt_figsize) == 0):
set_plot_size.g_plt_figsize = plt.rcParams["figure.figsize"]
size = []
size.append(set_plot_size.g_plt_figsize[0] * xrate)
size.append(set_plot_size.g_plt_figsize[1] * yrate)
plt.figure(figsize=size)
set_plot_size.g_plt_figsize = []
실험01 다이오드의 측정 : DMM¶
실험01-01 다이오드 순, 역방향 전압 측정하기¶
실험 방법¶
- Si 다이오드 (1N4148)
- Ge 다이오드 (1N270)
- 전원용 다이오드 (1N4004)
- 제너 다이오드 (1N5234)
- LED (빨간색)
- LED (녹색)
- LED (흰색)
In [2]:
display(Image("./images/ch02_ep01_01_circuit.png", width=1000))
실험 결과¶
In [3]:
# 멀티미터 측정 결과가 OL이면 inf로 기록한다.
V_D_S_1N4148_forward_V = 0.564
V_D_S_1N4148_reverse_V = inf
V_D_G_1N270_forward_V = 0.183
V_D_G_1N270_reverse_V = inf
V_D_R_1N4004_forward_V = 0.530
V_D_R_1N4004_reverse_V = inf
V_D_Z_1N5234_forward_V = 0.718
V_D_Z_1N5234_reverse_V = inf
V_D_L_R_forward_V = 1.752
V_D_L_R_reverse_V = inf
V_D_L_G_forward_V = 1.773
V_D_L_G_reverse_V = inf
V_D_L_W_forward_V = inf
V_D_L_W_reverse_V = inf
실험02 다이오드 전압-전류 특성 측정¶
실험02-01 다이오드 전압-전류 특성 측정하기¶
실험 방법¶
- Vi: 직류 0.4 ~ 10 V
In [4]:
display(Image("./images/ch02_ep02_01_circuit.png", width=400))
실험 결과¶
제작한 회로¶
In [5]:
display(Image("./data/ch02_ep02_01_result_circuit.jpg", width=1000))
멀티미터 측정값¶
In [6]:
V_S_V = [ 0.400, 0.600, 0.800, 1.000, 2.000, 3.000, 4.000, 5.000, 6.000, 7.000, 8.000, 9.000, 10.000]
V_I_V = [ 0.40 , 0.60 , 0.80 , 1.01 , 2.02 , 3.02 , 4.02 , 5.02 , 6.03 , 7.04 , 8.06 , 9.06 , 10.07]
V_D_V = [ 0.395, 0.497, 0.541, 0.564, 0.620, 0.646, 0.663, 0.676, 0.687, 0.695, 0.703, 0.710, 0.716]
결과 분석¶
In [7]:
# 저항 R1의 크기와, 이 저항에 걸리는 전압값을 사용해 다이오드, D1에 흐르는 전류값을 계산한다.
R1_ohm = 1000
V_D_V = np.array(V_D_V)
V_I_V = np.array(V_I_V)
I_D_A = ((V_I_V - V_D_V) / R1_ohm)
I_D_mA = I_D_A * 1000
print_array('I_D_mA', I_D_mA)
# 다이오드의 I-V 특성 곡선을 그린다.
plt.xlabel('V_D_V')
plt.ylabel('I_D_mA')
plt.axhline(0, color='black')
plt.axvline(0, color='black')
plt.axvline(0.7, color='green')
plt.xlim(-0.08, 0.8)
plt.ylim(-1.0, 10.0)
plt.plot(V_D_V, I_D_mA, 'b.-')
plt.show()
I_D_mA = [ 0.005, 0.103, 0.259, 0.446, 1.400, 2.374, 3.357, 4.344, 5.343, 6.345, 7.357, 8.350, 9.354]
In [8]:
# 다이오드 특성 곡선에서 정전압 등가모델용 V_cut_in을 구한다.
V_cut_in_V = 0.7
print("V_cut_in_V = {:8.3f}".format(V_cut_in_V))
V_cut_in_V = 0.700
In [9]:
# 다이오드 특성 곡선에서 부분선형 등가모델용 V_cut_in과 r_D을 구한다.
i1 = 7
i2 = 12
xs = V_D_V
ys = I_D_mA
m = (ys[i2] - ys[i1]) / (xs[i2] - xs[i1])
b = ys[i2] - m * xs[i2]
tf = lambda x: m * x + b
gradient = m
txs = np.arange(0.6, 0.8, 0.01)
tys = tf(txs)
V_cut_in_V = np.interp(0.0, tys, txs)
r_D__V_div_mA = 1. / gradient
r_D_ohm = r_D__V_div_mA * 1000.
plt.xlabel('V_D_V')
plt.ylabel('I_D_mA')
plt.axhline(0, color='black')
plt.axvline(0, color='black')
plt.xlim(-0.08, 0.8)
plt.ylim(-1.0, 10.0)
plt.plot(xs, ys, 'b.-')
plt.plot(txs, tys, 'g-')
plt.scatter(V_cut_in_V, 0)
plt.scatter(xs[i1], ys[i1])
plt.scatter(xs[i2], ys[i2])
plt.text(V_cut_in_V-0.2, 0-1.0, print_value_to_string('V_cut_in_V', V_cut_in_V))
plt.show()
print("Point A: {}, {}, {}".format(V_S_V[i1], xs[i1], ys[i1]))
print("Point B: {}, {}, {}".format(V_S_V[i2], xs[i2], ys[i2]))
print()
print("r_D_ohm = {:8.3f}".format(r_D_ohm))
print("V_cut_in_V = {:8.3f}".format(V_cut_in_V))
Point A: 5.0, 0.676, 4.343999999999999 Point B: 10.0, 0.716, 9.354000000000001 r_D_ohm = 7.984 V_cut_in_V = 0.641
실험03 리미터 회로¶
실험03-01 리미터 만들기¶
실험 방법¶
- 다이오드:
- Si 다이오드 (1N4148)
- Ge 다이오드 (1N270)
- 전원용 다이오드 (1N4004)
- 제너 다이오드 (1N5234)
- LED (빨간색)
- LED (녹색)
- LED (흰색)
In [10]:
display(Image("./images/ch02_ep03_01_circuit.png", width=400))
실험 결과¶
제작한 회로¶
In [11]:
display(Image("./data/ch02_ep03_01_result_circuit.jpg", width=1000))
멀티미터 측정값¶
In [12]:
V_D_S_1N4148_V = 0.677
V_D_G_1N270_V = 0.263
V_D_R_1N4004_V = 0.640
V_D_Z_1N5234_V = 0.775
V_D_L_R_V = 1.922
V_D_L_G_V = 1.952
V_D_L_W_V = 2.649
실험04 피크검출기 회로¶
실험04-01 피크검출기 만들기¶
실험 방법¶
- 다이오드: 1N4148
- Vi: 정현파, 주파수 1 kHz, 크기 8 ~ 12 Vpp
In [13]:
display(Image("./images/ch02_ep04_01_circuit.png", width=400))
실험 결과¶
제작한 회로¶
In [14]:
display(Image("./data/ch02_ep04_01_result_circuit.jpg", width=1000))
오실로스코프 화면¶
In [15]:
# 8 Vpp
display(Image("./data/ch02_ep04_02_result_08vpp.png", width=600))
# 10 Vpp
display(Image("./data/ch02_ep04_03_result_10vpp.png", width=600))
# 12 Vpp
display(Image("./data/ch02_ep04_04_result_12vpp.png", width=600))
# 8 Vpp
display(Image("./data/ch02_ep04_05_result_08vpp.png", width=600))
결과 분석¶
In [16]:
# 실험 결과 파일을 읽는다.
data_02_08vpp = get_oscilloscpoe_result_tektronix('./data/ch02_ep04_02_result_08vpp.csv')
data_03_10vpp = get_oscilloscpoe_result_tektronix('./data/ch02_ep04_03_result_10vpp.csv')
data_04_12vpp = get_oscilloscpoe_result_tektronix('./data/ch02_ep04_04_result_12vpp.csv')
data_05_08vpp = get_oscilloscpoe_result_tektronix('./data/ch02_ep04_05_result_08vpp.csv')
# 실험 결과에서 시간, 입력 전압, 출력 전압을 가져온다.
times_02_08vpp = data_02_08vpp['TIME']
vins_02_08vpp = data_02_08vpp['Sample CH1']
vouts_02_08vpp = data_02_08vpp['Sample CH2']
times_03_10vpp = data_03_10vpp['TIME']
vins_03_10vpp = data_03_10vpp['Sample CH1']
vouts_03_10vpp = data_03_10vpp['Sample CH2']
times_04_12vpp = data_04_12vpp['TIME']
vins_04_12vpp = data_04_12vpp['Sample CH1']
vouts_04_12vpp = data_04_12vpp['Sample CH2']
times_05_08vpp = data_05_08vpp['TIME']
vins_05_08vpp = data_05_08vpp['Sample CH1']
vouts_05_08vpp = data_05_08vpp['Sample CH2']
# 필터를 적용해 잡음을 줄인다.
vins_02_08vpp = savgol_filter(vins_02_08vpp, 100, 2)
vouts_02_08vpp = savgol_filter(vouts_02_08vpp, 100, 2)
vins_03_10vpp = savgol_filter(vins_03_10vpp, 100, 2)
vouts_03_10vpp = savgol_filter(vouts_03_10vpp, 100, 2)
vins_04_12vpp = savgol_filter(vins_04_12vpp, 100, 2)
vouts_04_12vpp = savgol_filter(vouts_04_12vpp, 100, 2)
vins_05_08vpp = savgol_filter(vins_05_08vpp, 100, 2)
vouts_05_08vpp = savgol_filter(vouts_05_08vpp, 100, 2)
# 시간을 x축, 전압들을 y축으로 하는 그래프를 그리고, v_out을 구한다.
plt.title("02_08vpp")
plt.xlabel('TIME_s')
plt.ylabel('V_V')
plt.axhline(0, color='black')
plt.axvline(0, color='black')
plt.ylim((-7, 7))
draw_plot(times_02_08vpp, vins_02_08vpp, 'V(IN)', 0)
draw_plot(times_02_08vpp, vouts_02_08vpp, 'V(OUT)', 1)
plt.show()
V_OUT_mean_V_02_08vpp = vouts_02_08vpp.mean()
print_value("V_OUT_mean_V_02_08vpp", V_OUT_mean_V_02_08vpp)
print()
plt.title("03_10vpp")
plt.xlabel('TIME_s')
plt.ylabel('V_V')
plt.axhline(0, color='black')
plt.axvline(0, color='black')
plt.ylim((-7, 7))
draw_plot(times_03_10vpp, vins_03_10vpp, 'V(IN)', 0)
draw_plot(times_03_10vpp, vouts_03_10vpp, 'V(OUT)', 1)
plt.show()
V_OUT_mean_V_03_10vpp = vouts_03_10vpp.mean()
print_value("V_OUT_mean_V_03_10vpp", V_OUT_mean_V_03_10vpp)
print()
plt.title("04_12vpp")
plt.xlabel('TIME_s')
plt.ylabel('V_V')
plt.axhline(0, color='black')
plt.axvline(0, color='black')
plt.ylim((-7, 7))
draw_plot(times_04_12vpp, vins_04_12vpp, 'V(IN)', 0)
draw_plot(times_04_12vpp, vouts_04_12vpp, 'V(OUT)', 1)
plt.show()
V_OUT_mean_V_04_12vpp = vouts_04_12vpp.mean()
print_value("V_OUT_mean_V_04_12vpp", V_OUT_mean_V_04_12vpp)
print()
plt.title("05_08vpp")
plt.xlabel('TIME_s')
plt.ylabel('V_V')
plt.axhline(0, color='black')
plt.axvline(0, color='black')
plt.ylim((-7, 7))
draw_plot(times_05_08vpp, vins_05_08vpp, 'V(IN)', 0)
draw_plot(times_05_08vpp, vouts_05_08vpp, 'V(OUT)', 1)
plt.show()
V_OUT_mean_V_05_08vpp = vouts_05_08vpp.mean()
print_value("V_OUT_mean_V_05_08vpp", V_OUT_mean_V_05_08vpp)
print()
data['TIME'] : sample number = 5208 data['Glitch Capture CH1'] : sample number = 5208 data['Sample CH1'] : sample number = 5208 data['Glitch Capture CH2'] : sample number = 5208 data['Sample CH2'] : sample number = 5208 data['TIME'] : sample number = 5208 data['Glitch Capture CH1'] : sample number = 5208 data['Sample CH1'] : sample number = 5208 data['Glitch Capture CH2'] : sample number = 5208 data['Sample CH2'] : sample number = 5208 data['TIME'] : sample number = 5208 data['Glitch Capture CH1'] : sample number = 5208 data['Sample CH1'] : sample number = 5208 data['Glitch Capture CH2'] : sample number = 5208 data['Sample CH2'] : sample number = 5208 data['TIME'] : sample number = 5208 data['Glitch Capture CH1'] : sample number = 5208 data['Sample CH1'] : sample number = 5208 data['Glitch Capture CH2'] : sample number = 5208 data['Sample CH2'] : sample number = 5208
V_OUT_mean_V_02_08vpp = 3.601
V_OUT_mean_V_03_10vpp = 4.619
V_OUT_mean_V_04_12vpp = 5.595
V_OUT_mean_V_05_08vpp = 5.502
실험05 정류기 회로¶
실험05-01 정류기 만들기¶
실험 방법¶
- 다이오드: 1N4004
- Vi: 정현파, 주파수 1 kHz, 크기 8 Vpp
In [17]:
display(Image("./images/ch02_ep05_01_circuit.png", width=400))
실험 결과¶
제작한 회로¶
In [18]:
display(Image("./data/ch02_ep05_01_result_circuit.jpg", width=1000))
오실로스코프 화면¶
In [19]:
display(Image("./data/ch02_ep05_02_result.png", width=600))
display(Image("./data/ch02_ep05_03_result_xy.png", width=600))
결과 분석¶
In [20]:
# 실험 결과 파일을 읽는다.
data = get_oscilloscpoe_result_tektronix('./data/ch02_ep05_02_result.csv')
# 실험 결과에서 시간, 입력 전압, 출력 전압을 가져온다.
times = data['TIME']
vins = data['Sample CH1']
vouts = data['Sample CH2']
# 필터를 적용해 잡음을 줄인다.
vins = savgol_filter(vins, 100, 2)
vouts = savgol_filter(vouts, 100, 2)
# 시간을 x축, 전압들을 y축으로 하는 그래프를 그린다.
plt.xlabel('TIME_s')
plt.ylabel('V_V')
plt.axhline(0, color='black')
plt.axvline(0, color='black')
draw_plot(times, vins, 'V(IN)', 0)
draw_plot(times, vouts, 'V(OUT)', 1)
plt.show()
# 입력 전압을 x축, 출력 전압을 y축으로 하는 그래프를 그린다.
plt.xlabel('V_IN_V')
plt.ylabel('V_OUT_V')
plt.axhline(0, color='black')
plt.axvline(0, color='black')
draw_plot(vins, vouts, "XY", 0)
plt.show()
data['TIME'] : sample number = 5208 data['Glitch Capture CH1'] : sample number = 5208 data['Sample CH1'] : sample number = 5208 data['Glitch Capture CH2'] : sample number = 5208 data['Sample CH2'] : sample number = 5208